package org.osll.tictactoe.client.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.event.ChangeListener;

import org.osll.tictactoe.Control;
import org.osll.tictactoe.CurrentMove;
import org.osll.tictactoe.Move;
import org.osll.tictactoe.Team;
import org.osll.tictactoe.engine.GameOverException;
import org.osll.tictactoe.engine.MoveImpl;

public class MainFrame extends JFrame {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -1972226997401636014L;
	
	private Control control = null;
	private Field field = null;
	private Team team;
	private String userName;
	
	private FieldThread fieldThread = new FieldThread();

	private StatusBar statusBar;
	
	private class FieldThread implements Runnable {
		
		private Move lastMove = new MoveImpl(0,0,Team.U);
		private ArrayList<ChangeListener> changeListeneres = new ArrayList<ChangeListener>();

		@Override
		public void run() {
			for(;;) {
				if(!control.isStarted()) {
					statusBar.setText("Игра не началась");
					try {
						Thread.sleep(100);
						continue;
					} catch (InterruptedException e) {
						break;
					}
				} else {
					if(team == Team.X) {
						statusBar.setInfo(userName +", Вы играете против " +control.getApponentName() + " за команду крестиков.");
					} else {
						statusBar.setInfo(userName +", Вы играете против " +control.getApponentName() + " за команду ноликов.");
					}
				}
				try {
					Move move = control.getApponentMove();
					if(!lastMove.equals(move)) {
						lastMove = move; 
						field.addMove(move);
						statusBar.setText("Получен ход противника");
						for (ChangeListener it : changeListeneres) {
							it.stateChanged(null);
						}
					}
				} catch(GameOverException e) {
					statusBar.setText("Игра окончена. Вы проиграли.");
					return;

				} catch (IllegalStateException e) {
					
				}
				try {
					CurrentMove cm = control.getMoveEndTime();
					if(cm.getTeam() != team) {
						statusBar.setText("Ожидание хода противника");
						try {
							Thread.sleep(800);
						} catch (InterruptedException e) {
							break;
						}
					} else {
						statusBar.setText("Ваш ход. вам осталось думать " + cm.getTimeToOver()/1000 + " секунд");
						try {
							Thread.sleep(200);
						} catch (InterruptedException e) {
							break;
						}
						continue;
					}
				} catch (IllegalStateException e) {
					continue;
				}
			}
		}
		
		void addChangeListener(ChangeListener l) {
			changeListeneres.add(l);
		}
	}
	
	public MainFrame(final Control control, Team team, String userName) {
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		statusBar = new StatusBar(this);
		setTitle("Распределенная игра крестики-нолики на большом поле, " + userName);
		this.control = control;
		new Thread(fieldThread).start();
		this.field = new Field(control.getSize());
		this.team = team;
		this.userName = userName;
		Canvas canvas = new Canvas(field, control, statusBar,team);
		fieldThread.addChangeListener(canvas);
		setLayout(new BorderLayout());

		add(canvas, BorderLayout.CENTER);
		add(statusBar, BorderLayout.SOUTH);
		addWindowListener(new WindowAdapter() {

			public void windowClosing(WindowEvent e) {
            	control.disconnect();
            }
        });
		setMinimumSize(new Dimension(640,480));
		pack();
		
	}
}
